//
//  LFTMCSessionViewController.m
//  lofter-mvpcourse-ios
//
//  Created by Thomas Quan on 2017/5/2.
//  Copyright © 2017年 undefined-zola. All rights reserved.
//

#import "LFTMCSessionViewController.h"
@import MobileCoreServices;
@import AVFoundation;
#import "Reachability.h"
#import "UIActionSheet+NTESBlock.h"
#import "NTESCustomSysNotificationSender.h"
#import "LFTMCSessionConfig.h"
#import "NIMMediaItem.h"
#import "NTESSessionMsgConverter.h"
#import "NTESFileLocationHelper.h"
#import "NTESSessionMsgConverter.h"
#import "UIView+Toast.h"
#import "NTESSnapchatAttachment.h"
#import "NTESJanKenPonAttachment.h"
#import "NTESFileTransSelectViewController.h"
#import "NTESChartletAttachment.h"
#import "NTESGalleryViewController.h"
#import "NTESVideoViewController.h"
#import "NTESFilePreViewController.h"
#import "NTESAudio2TextViewController.h"
#import "NSDictionary+NTESJson.h"
#import "NTESSessionRemoteHistoryViewController.h"
#import "UIView+NTES.h"
#import "NTESBundleSetting.h"
#import "NTESPersonalCardViewController.h"
#import "NTESSessionSnapchatContentView.h"
#import "NTESSessionLocalHistoryViewController.h"
#import "NIMContactSelectViewController.h"
#import "SVProgressHUD.h"
#import "NTESSessionCardViewController.h"
#import "NTESFPSLabel.h"
#import "UIAlertView+NTESBlock.h"
#import "NIMKit.h"
#import "NTESSessionUtil.h"
#import "NIMKitMediaFetcher.h"
#import "NIMKitLocationPoint.h"
#import "NIMLocationViewController.h"
#import "NIMKitInfoFetchOption.h"
#import "NIMCustomLeftBarView.h"
#import "NIMAdvancedTeamCardViewController.h"
#import "LFTMCTeamCardViewController.h"
#import "UITableView+LFTMCScrollTo.h"
#import "NTESGlobalMacro.h"
#import "NSUserDefaults+NSIndexPath.h"
#import "LFTMCPrefixHeader.h"
#import "UIButton+LFTMCBlock.h"
#import "LFTMCUnReadAlertView.h"
#import "UIView+NIM.h"
#import "LFTMCTeamMemberCardViewController.h"
#import "PhotoBrowser.h"
#import "UIImageView+WebCache.h"
#import "NIMSessionDataSourceImpl.h"
#import "NIMSessionInteractorImpl.h"
#import "LFTMCUtil.h"
#import "LFTMCStatusHintView.h"
#import "LFTMCUnReadAlertView.h"
#import "NTESService.h"

@interface LFTMCGalleryItem : NSObject
@property (nonatomic,copy)    NSString    *thumbPath;
@property (nonatomic,copy)    NSString    *imageURL;
@property (nonatomic,strong)  NIMMessage  *message;
@end

@implementation LFTMCGalleryItem

@end

NSString *NTESNotificationLogout = @"NTESNotificationLogout";

@interface LFTMCSessionViewController ()
<UIImagePickerControllerDelegate,
UINavigationControllerDelegate,
NIMSystemNotificationManagerDelegate,
NIMMediaManagerDelegate,
NIMContactSelectDelegate,
PBViewControllerDelegate,
PBViewControllerDataSource,
LFTMCTeamCardViewControllerDelegate,
NIMChatManagerDelegate,
LFTMCUnreadAlertViewDelegate,
NIMTeamManagerDelegate,
NIMLoginManagerDelegate,
NIMSDKConfigDelegate>

@property (nonatomic,strong)    LFTMCSessionConfig       *sessionConfig;
@property (nonatomic,strong)    UIImagePickerController *imagePicker;
@property (nonatomic,strong)    UIView *currentSingleSnapView;
@property (nonatomic,strong)    NTESFPSLabel *fpsLabel;
@property (nonatomic,strong)    NIMKitMediaFetcher *mediaFetcher;

@property (nonatomic,strong)    NSIndexPath *lastVisibleIndexPath;

@property (nonatomic, strong)   NSMutableArray<LFTMCGalleryItem *> *galleryItems;

@property (nonatomic, strong)   LFTMCStatusHintView *statusView;

@property (nonatomic, strong)   LFTMCUnReadAlertView *unreadAlert;

@property (nonatomic, strong)   NSDate *lastSendRecordDate;
@property (nonatomic, strong)   NSDate *lastTapCellData;

@end

@implementation LFTMCSessionViewController

- (instancetype)initWithSession:(NIMSession *)session
{
    self = [super initWithSession:session];
    if (self) {
        
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    DDLogInfo(@"enter session, id = %@",self.session.sessionId);
    [self setupNav];
    if ([[NTESBundleSetting sharedConfig] showFps])
    {
        self.fpsLabel = [[NTESFPSLabel alloc] initWithFrame:CGRectZero];
        [self.view addSubview:self.fpsLabel];
        self.fpsLabel.right = self.view.width;
        self.fpsLabel.top   = self.tableView.top + self.tableView.contentInset.top;
    }
    
    //删除最近会话列表中有人@你的标记
    [NTESSessionUtil removeRecentSessionAtMark:self.session];
    
    [self setupStatusView];
    [self setupUnreadAlertView];
    [self LFTMC_AddListener];

    
}

- (void)dealloc
{
    [[[NIMSDK sharedSDK] systemNotificationManager] removeDelegate:self];
    [[NIMSDK sharedSDK].teamManager removeDelegate:self];
    [_fpsLabel invalidate];
}

- (void)viewDidLayoutSubviews{
    [super viewDidLayoutSubviews];
    self.fpsLabel.right = self.view.width;
    self.fpsLabel.top   = self.tableView.top + self.tableView.contentInset.top;
    
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    self.lastSendRecordDate = [NSDate new];
    NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:self.session.sessionId];
    // 获取当前课程状态
    LFTMCStatus status = [LFTMCUtil statusForTeamByModel:[LFTMCUtil sharedInstance].teamModel mutedMembers:[LFTMCUtil sharedInstance].mutedMembers];
    [self.statusView refreshStatus:status];
    
    [self refreshNav];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didScrollToButtom) name:@"DismissUnreadAlert" object:nil];
}

- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    
    [[NIMSDK sharedSDK].mediaManager stopRecord];
//    [[NIMSDK sharedSDK].mediaManager stopPlay];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"DismissUnreadAlert" object:nil];
}

#pragma LFTMCTeamCardViewControllerDelegate

- (void)setOnlyTeacher:(BOOL)flag {
    NSString *sessionId = self.session.sessionId;
    NSArray *teachers;
    NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:self.session.sessionId];
    NSString *string = team.serverCustomInfo;
    NSDictionary *serverCustom = [LFTMCUtil stringToDictionary:string];
    if (serverCustom[kTagTeachers]) {
        teachers = serverCustom[kTagTeachers];
    }
    
    [LFTMCUtil setOnlySeeTeacher:flag inSession:sessionId];
//    [LFTMCUtil setTeacherIds:teachers inSession:sessionId];
    
    [self.interactor resetMessages];
    [self.tableView reloadData];
    [self.tableView lftmc_scrollToBottom:NO];
}

- (id<NIMSessionConfig>)sessionConfig
{
    if (_sessionConfig == nil) {
        _sessionConfig = [[LFTMCSessionConfig alloc] init];
    }
    return _sessionConfig;
}


#pragma mark - NIMSystemNotificationManagerProcol
- (void)onReceiveCustomSystemNotification:(NIMCustomSystemNotification *)notification
{
    if (!notification.sendToOnlineUsersOnly) {
        return;
    }
}

#pragma mark - NIMSessionConfiguratorDelegate

- (void)didFetchMessageData
{
    [super didFetchMessageData];

}

- (void)didRefreshMessageData
{
    [self refreshNav];
    [self.tableView reloadData];
}

- (NSString *)sessionTitle{
    NIMTeam *team = [[[NIMSDK sharedSDK] teamManager] teamById:self.session.sessionId];
    NSString *title = [LFTMCUtil titleMaker:team.teamName];
    return title;
}

#pragma NIMChatManagerDelegate
- (void)willSendMessage:(NIMMessage *)message
{
    
    id<NIMSessionInteractor> interactor = self.interactor;
    
    if ([message.session isEqual:self.session]) {
        if ([interactor findMessageModel:message]) {
            [interactor updateMessage:message];
        }else{
            [interactor addMessages:@[message]];
        }
    }
    
}

//发送结果
- (void)sendMessage:(NIMMessage *)message didCompleteWithError:(NSError *)error
{
    if ([message.session isEqual:self.session]) {
        [self.interactor updateMessage:message];
    }
    if (error) {
        [self.sessionInputView endEditing:YES];
        LFTMCStatus status = [LFTMCUtil statusForTeamByModel:[LFTMCUtil sharedInstance].teamModel mutedMembers:[LFTMCUtil sharedInstance].mutedMembers];
        [self.statusView refreshStatus:status];
        if (status == LFTMCStatusPersonMuted) {
            [self.view makeToast:@"您已被禁言" duration:2.0 position:CSToastPositionCenter];
        }
    }
    
}

//发送进度
-(void)sendMessage:(NIMMessage *)message progress:(float)progress
{
    if ([message.session isEqual:self.session]) {
        [self.interactor updateMessage:message];
    }
}

//接收消息
- (void)onRecvMessages:(NSArray *)messages
{
    NIMMessage *message = messages.firstObject;
    NIMSession *session = message.session;
    if (![session isEqual:self.session] || !messages.count){
        return;
    }
    
    // 过滤消息，仅UI层，数据库不受影响
    NSArray *filteredMessage = [LFTMCUtil filterMessages:messages SessionId:self.session.sessionId isNeedModel:NO];
    
    [self uiAddMessages:filteredMessage];
    [self sendMessageReceipt:filteredMessage];
    
    // 判断当前是否在聊天页的最底部
    // 不在的话才显示未读消息条，
    if (![LFTMCUtil shouldScrollToButtom:self.tableView]) {
        [self.unreadAlert updateCount:filteredMessage.count];
    }
    
}

#pragma mark - 已读回执
- (void)sendMessageReceipt:(NSArray *)messages
{
    if ([self shouldHandleReceipt]) {
        [self.interactor sendMessageReceipt:messages];
    }
}

- (BOOL)shouldHandleReceipt
{
    return self.session.sessionType == NIMSessionTypeP2P &&
    [self.sessionConfig respondsToSelector:@selector(shouldHandleReceipt)] &&
    [self.sessionConfig shouldHandleReceipt];
}

- (void)onTextChanged:(id)sender
{
    
}

- (void)onSelectChartlet:(NSString *)chartletId
                 catalog:(NSString *)catalogId
{
    NTESChartletAttachment *attachment = [[NTESChartletAttachment alloc] init];
    attachment.chartletId = chartletId;
    attachment.chartletCatalog = catalogId;
    [self sendMessage:[NTESSessionMsgConverter msgWithChartletAttachment:attachment]];
}


#pragma mark - 录音事件
- (void)onRecordFailed:(NSError *)error
{
    [self.view makeToast:@"录音失败" duration:2 position:CSToastPositionCenter];
}

- (BOOL)recordFileCanBeSend:(NSString *)filepath
{
    NSURL    *URL = [NSURL fileURLWithPath:filepath];
    AVURLAsset *urlAsset = [[AVURLAsset alloc]initWithURL:URL options:nil];
    CMTime time = urlAsset.duration;
    CGFloat mediaLength = CMTimeGetSeconds(time);
    return mediaLength > 2;
}

- (void)showRecordFileNotSendReason
{
    if ([[NSDate new] timeIntervalSinceDate:self.lastSendRecordDate] > 1.0f) {
        [self.view makeToast:@"录音时间太短" duration:0.2f position:CSToastPositionCenter];
        self.lastSendRecordDate = [NSDate new];
    }
    
}

#pragma mark - Cell事件
- (BOOL)onTapCell:(NIMKitEvent *)event
{
    if ([[NSDate new] timeIntervalSinceDate:self.lastTapCellData] < 1.0f) {
        self.lastTapCellData = [NSDate new];
        return NO;
    }
    BOOL handled = [super onTapCell:event];
    NSString *eventName = event.eventName;
    if ([eventName isEqualToString:NIMKitEventNameTapContent])
    {
        NIMMessage *message = event.messageModel.message;
        NSDictionary *actions = [self cellActions];
        NSString *value = actions[@(message.messageType)];
        if (value) {
            SEL selector = NSSelectorFromString(value);
            if (selector && [self respondsToSelector:selector]) {
                SuppressPerformSelectorLeakWarning([self performSelector:selector withObject:message]);
                handled = YES;
            }
        }
    }
    else if([eventName isEqualToString:NIMKitEventNameTapLabelLink])
    {
        NSString *link = event.data;
        [self.view makeToast:[NSString stringWithFormat:@"tap link : %@",link]
                    duration:2
                    position:CSToastPositionCenter];
        handled = YES;
    }
    else if([eventName isEqualToString:NIMDemoEventNameOpenSnapPicture])
    {
        NIMCustomObject *object = event.messageModel.message.messageObject;
        NTESSnapchatAttachment *attachment = (NTESSnapchatAttachment *)object.attachment;
        if(attachment.isFired){
            return handled;
        }
        UIView *sender = event.data;
        self.currentSingleSnapView = [NTESGalleryViewController alertSingleSnapViewWithMessage:object.message baseView:sender];
        handled = YES;
    }
    else if([eventName isEqualToString:NIMDemoEventNameCloseSnapPicture])
    {
        //点击很快的时候可能会触发两次查看，所以这里不管有没有查看过 先强直销毁掉
        NIMCustomObject *object = event.messageModel.message.messageObject;
        UIView *senderView = event.data;
        [senderView dismissPresentedView:YES complete:nil];
        
        NTESSnapchatAttachment *attachment = (NTESSnapchatAttachment *)object.attachment;
        if(attachment.isFired){
            return handled;
        }
        attachment.isFired  = YES;
        NIMMessage *message = object.message;
        if ([NTESBundleSetting sharedConfig].autoRemoveSnapMessage) {
            [[NIMSDK sharedSDK].conversationManager deleteMessage:message];
            [self uiDeleteMessage:message];
            
        }else{
            [[NIMSDK sharedSDK].conversationManager updateMessage:message forSession:message.session completion:nil];
            [self uiUpdateMessage:message];
        }
        [[NSFileManager defaultManager] removeItemAtPath:attachment.filepath error:nil];
        handled = YES;
        self.currentSingleSnapView = nil;
    }
    
    if (!handled) {
        NSAssert(0, @"invalid event");
    }
    return handled;
}

- (BOOL)onTapAvatar:(NSString *)userId{
    [[LFTMCUtil sharedInstance].dataSource lftmc_trackEventID:@"IMUserCardClick"
                                                     category:nil
                                                        label:nil
                                                   attributes:nil];
    LFTMCTeamMemberCardViewController *vc = [[LFTMCTeamMemberCardViewController alloc] initWithUserId:userId team:self.session.sessionId];
    [self.navigationController pushViewController:vc animated:YES];
    
    return YES;
}


#pragma mark - PBViewControllerDataSource

- (NSInteger)numberOfPagesInViewController:(PBViewController *)viewController {
    return self.galleryItems.count;
}

- (void)viewController:(PBViewController *)viewController presentImageView:(UIImageView *)imageView forPageAtIndex:(NSInteger)index progressHandler:(void (^)(NSInteger, NSInteger))progressHandler {
//    __weak typeof(imageView) wImageView = imageView;
    UIImage *thumbImage = [UIImage imageWithContentsOfFile:[self.galleryItems[index] thumbPath]];
    NSString *urlString = [self.galleryItems[index] imageURL];
    NSArray *urlArr = [urlString componentsSeparatedByString:@"?"];
    NSString *lftmcUrlString = [NSString stringWithFormat:@"%@?imageView&thumbnail=3000x3000&type=jpg", [urlArr firstObject]];
    NSURL *url = [NSURL URLWithString:lftmcUrlString];
    [imageView sd_setImageWithURL:url
                 placeholderImage:thumbImage
                          options:SDWebImageRetryFailed
                         progress:progressHandler
                        completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
                            if (error) {
                                [imageView makeToast:@"下载图片失败"
                                             duration:2
                                             position:CSToastPositionCenter];
                            }
                            
                            
    }];
}

#pragma mark - PBViewControllerDelegate

- (void)viewController:(PBViewController *)viewController didSingleTapedPageAtIndex:(NSInteger)index presentedImage:(UIImage *)presentedImage {
    [viewController dismissViewControllerAnimated:YES completion:nil];
}

- (void)viewController:(nonnull PBViewController *)viewController didLongPressedPageAtIndex:(NSInteger)index presentedImage:(nullable UIImage *)presentedImage {
    [[LFTMCUtil sharedInstance].dataSource lftmc_trackEventID:@"ClickIMPicture_Press"
                                                     category:nil
                                                        label:nil
                                                   attributes:nil];
    
    __weak typeof(self) wself = self;
    __block NSInteger i = index;
    __block BOOL isFind = NO;
    dispatch_block_t jumpBlock = ^{
        NIMMessage *message = [self.galleryItems[i] message];
        __block NIMMessageModel *model = [[NIMMessageModel alloc] initWithMessage:message];
        
        NSArray *items = [self.interactor items];
        [items enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
            if ([obj isKindOfClass:[NIMMessageModel class]]) {
                if ([model isEqual:obj]) {
                    i = idx;
                    isFind = YES;
                    *stop = YES;
                }
            }
        }];
        if (isFind) {
            NSIndexPath *indexpath = [NSIndexPath indexPathForRow:i inSection:0];
            [wself.tableView lftmc_scrollToLastPosition:indexpath animation:YES];
        } else {
            
        }
        
        [viewController dismissViewControllerAnimated:YES completion:nil];
    };
    
    dispatch_block_t saveBlock = ^{
        UIImageWriteToSavedPhotosAlbum(presentedImage, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);
    };
    
    UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"选择操作" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    
    UIAlertAction *jump = [UIAlertAction actionWithTitle:@"定位到聊天位置"
                                                    style:UIAlertActionStyleDestructive
                                                  handler:^(UIAlertAction * _Nonnull action) {
                                                      
                                                      jumpBlock();
                                                      
                                                  }];
    
    UIAlertAction *save = [UIAlertAction actionWithTitle:@"保存到本地" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        saveBlock();
    }];
    
    UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    
    [alertVC addAction:jump];
    [alertVC addAction:cancel];
#ifdef TEST
    [alertVC addAction:save];
#endif

    [viewController presentViewController:alertVC animated:YES completion:nil];
}

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    NSString *msg = nil;
    if (!error) {
        msg = @"下载成功，已为您保存至相册";
    }
    else {
        msg = @"未授权访问您的照片，请您在设置中进行权限设置后重试";
    }
    [self.view makeToast:msg duration:2.0 position:CSToastPositionBottom];
}





#pragma mark - Cell Actions
- (void)showImage:(NIMMessage *)message
{
    NSLog(@"%@", [NSDate new]);
    [[LFTMCUtil sharedInstance].dataSource lftmc_trackEventID:@"IMPictureClick"
                                                     category:nil
                                                        label:nil
                                                   attributes:nil];
    
    
    NSInteger count = [[self.interactor items] count];
    NSArray *items = [self.interactor items];
    __weak typeof(self) wself = self;
    
    self.galleryItems = [[NSMutableArray alloc] init];
    
//    [self.galleryItems removeAllObjects];
    __block NSUInteger current = 0;
    
    for (NIMMessageModel *model in items) {
        if ([model isKindOfClass:[NIMMessageModel class]]) {
            NIMMessage *msg = [model message];
            if (msg.messageType == NIMMessageTypeImage) {
                LFTMCGalleryItem *item = [[LFTMCGalleryItem alloc] init];
                NIMImageObject *object = msg.messageObject;
                if (!object) {
                    continue;
                }
                item.thumbPath = object.thumbPath;
                item.imageURL  = object.url;
                item.message   = msg;
                [self.galleryItems addObject:item];
                if ([msg.messageId isEqualToString:message.messageId]) {
                    current = self.galleryItems.count - 1;
                }
            }
        }
    }
    
    PBViewController *pbViewController = [PBViewController new];
    pbViewController.pb_dataSource = self;
    pbViewController.pb_delegate = self;
    pbViewController.pb_startPage = current;
    [self presentViewController:pbViewController animated:YES completion:nil];
    
    NIMImageObject *object = message.messageObject;
    if(![[NSFileManager defaultManager] fileExistsAtPath:object.thumbPath]){
        //如果缩略图下跪了，点进看大图的时候再去下一把缩略图
//        __weak typeof(self) wself = self;
        [[NIMSDK sharedSDK].resourceManager download:object.thumbUrl filepath:object.thumbPath progress:nil completion:^(NSError *error) {
            if (!error) {
                [wself uiUpdateMessage:message];
            }
        }];
    }
}

- (void)showVideo:(NIMMessage *)message
{
    NIMVideoObject *object = message.messageObject;
    NTESVideoViewController *playerViewController = [[NTESVideoViewController alloc] initWithVideoObject:object];
    [self.navigationController pushViewController:playerViewController animated:YES];
    if(![[NSFileManager defaultManager] fileExistsAtPath:object.coverPath]){
        //如果封面图下跪了，点进视频的时候再去下一把封面图
        __weak typeof(self) wself = self;
        [[NIMSDK sharedSDK].resourceManager download:object.coverUrl filepath:object.coverPath progress:nil completion:^(NSError *error) {
            if (!error) {
                [wself uiUpdateMessage:message];
            }
        }];
    }
}

- (void)showCustom:(NIMMessage *)message
{
    //普通的自定义消息点击事件可以在这里做哦~
}

#pragma mark - 导航按钮
- (void)moreAction:(id)sender {
    NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:self.session.sessionId];
    LFTMCTeamCardViewController *vc = [[LFTMCTeamCardViewController alloc] initWithTeam:team AndTeamModel:[LFTMCUtil sharedInstance].teamModel];
    vc.delegate = self;
    [[LFTMCUtil sharedInstance].dataSource lftmc_trackEventID:@"GourpMoreClick"
                                                     category:nil
                                                        label:nil
                                                   attributes:nil];
    [self.navigationController pushViewController:vc animated:YES];
}

#pragma mark - 菜单
- (NSArray *)menusItems:(NIMMessage *)message
{
    NSMutableArray *items = [NSMutableArray array];
    NSArray *defaultItems = [super menusItems:message];
    if (defaultItems) {
        [items addObjectsFromArray:defaultItems];
    }
    
    if ([NTESSessionUtil canMessageBeRevoked:message]) {
        [items addObject:[[UIMenuItem alloc] initWithTitle:@"撤回" action:@selector(revokeMessage:)]];
    }
    
    return items;
    
}

- (void)audio2Text:(id)sender
{
    NIMMessage *message = [self messageForMenu];
    __weak typeof(self) wself = self;
    NTESAudio2TextViewController *vc = [[NTESAudio2TextViewController alloc] initWithMessage:message];
    vc.completeHandler = ^(void){
        [wself uiUpdateMessage:message];
    };
    [self presentViewController:vc
                       animated:YES
                     completion:nil];
}


- (void)forwardMessage:(id)sender
{
    NIMMessage *message = [self messageForMenu];
    UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"选择会话类型" delegate:nil cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"个人",@"群组", nil];
    __weak typeof(self) weakSelf = self;
    [sheet showInView:self.view completionHandler:^(NSInteger index) {
        switch (index) {
            case 0:{
                NIMContactFriendSelectConfig *config = [[NIMContactFriendSelectConfig alloc] init];
                config.needMutiSelected = NO;
                NIMContactSelectViewController *vc = [[NIMContactSelectViewController alloc] initWithConfig:config];
                vc.finshBlock = ^(NSArray *array){
                    NSString *userId = array.firstObject;
                    NIMSession *session = [NIMSession session:userId type:NIMSessionTypeP2P];
                    [weakSelf forwardMessage:message toSession:session];
                };
                [vc show];
            }
                break;
            case 1:{
                NIMContactTeamSelectConfig *config = [[NIMContactTeamSelectConfig alloc] init];
                NIMContactSelectViewController *vc = [[NIMContactSelectViewController alloc] initWithConfig:config];
                vc.finshBlock = ^(NSArray *array){
                    NSString *teamId = array.firstObject;
                    NIMSession *session = [NIMSession session:teamId type:NIMSessionTypeTeam];
                    [weakSelf forwardMessage:message toSession:session];
                };
                [vc show];
            }
                break;
            case 2:
                break;
            default:
                break;
        }
    }];
}


- (void)revokeMessage:(id)sender
{
    NIMMessage *message = [self messageForMenu];
    __weak typeof(self) weakSelf = self;
    [[NIMSDK sharedSDK].chatManager revokeMessage:message completion:^(NSError * _Nullable error) {
        if (error) {
            if (error.code == NIMRemoteErrorCodeDomainExpireOld) {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"发送时间超过2分钟的消息，不能被撤回" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
                [alert show];
            }else{
//                DDLogError(@"revoke message eror code %zd",error.code);
                [weakSelf.view makeToast:@"消息撤回失败，请重试" duration:2.0 position:CSToastPositionCenter];
            }
        }
        else
        {
            NIMMessageModel *model = [self uiDeleteMessage:message];
            NIMMessage *tip = [NTESSessionMsgConverter msgWithTip:[NTESSessionUtil tipOnMessageRevoked:message]];
            tip.timestamp = model.messageTime;
            [self uiInsertMessages:@[tip]];
            
            tip.timestamp = message.timestamp;
            // saveMessage 方法执行成功后会触发 onRecvMessages: 回调，但是这个回调上来的 NIMMessage 时间为服务器时间，和界面上的时间有一定出入，所以要提前先在界面上插入一个和被删消息的界面时间相符的 Tip, 当触发 onRecvMessages: 回调时，组件判断这条消息已经被插入过了，就会忽略掉。
            [[NIMSDK sharedSDK].conversationManager saveMessage:tip forSession:message.session completion:nil];
        }
    }];
}


- (void)forwardMessage:(NIMMessage *)message toSession:(NIMSession *)session
{
    NSString *name;
    if (session.sessionType == NIMSessionTypeP2P)
    {
        NIMKitInfoFetchOption *option = [[NIMKitInfoFetchOption alloc] init];
        option.session = session;
        name = [[NIMKit sharedKit] infoByUser:session.sessionId option:option].showName;
    }
    else
    {
        name = [[NIMKit sharedKit] infoByTeam:session.sessionId option:nil].showName;
    }
    NSString *tip = [NSString stringWithFormat:@"确认转发给 %@ ?",name];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"确认转发" message:tip delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确认", nil];
    
    __weak typeof(self) weakSelf = self;
    [alert showAlertWithCompletionHandler:^(NSInteger index) {
        if(index == 1){
            [[NIMSDK sharedSDK].chatManager forwardMessage:message toSession:session error:nil];
            [weakSelf.view makeToast:@"已发送" duration:2.0 position:CSToastPositionCenter];
        }
    }];
}

#pragma mark - 辅助方法

- (void)sendSnapchatMessagePath:(NSString *)path
{
    NTESSnapchatAttachment *attachment = [[NTESSnapchatAttachment alloc] init];
    [attachment setImageFilePath:path];
    [self sendMessage:[NTESSessionMsgConverter msgWithSnapchatAttachment:attachment]];
}

- (void)sendImageMessagePath:(NSString *)path
{
    [self sendSnapchatMessagePath:path];
}

- (NSDictionary *)cellActions
{
    static NSDictionary *actions = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        actions = @{@(NIMMessageTypeImage) :    @"showImage:",
                    @(NIMMessageTypeVideo) :    @"showVideo:",
                    @(NIMMessageTypeLocation) : @"showLocation:",
                    @(NIMMessageTypeFile)  :    @"showFile:",
                    @(NIMMessageTypeCustom):    @"showCustom:"
                    };
    });
    return actions;
}

- (NIMKitMediaFetcher *)mediaFetcher
{
    if (!_mediaFetcher) {
        _mediaFetcher = [[NIMKitMediaFetcher alloc] init];
        _mediaFetcher.limit = 1;
        _mediaFetcher.mediaTypes = @[(NSString *)kUTTypeImage];
    }
    return _mediaFetcher;
}

- (void)close {
    [[LFTMCUtil sharedInstance].dataSource lftmc_trackEventID:@"IMClose"
                                                     category:nil
                                                        label:nil
                                                   attributes:nil];
    [[NIMSDK sharedSDK].loginManager logout:^(NSError * _Nullable error) {
        
        [self.navigationController dismissViewControllerAnimated:YES completion:nil];
        
        [_fpsLabel invalidate];
        [[NTESServiceManager sharedManager] destory];
        [self LFTMC_RemoveListener];
        
    }];

}

- (void)setupNav{    
    UIBarButtonItem *backButtonItem =
    [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"LFTMC_Back"]
                                     style:UIBarButtonItemStylePlain
                                    target:self
                                    action:@selector(close)];
    [backButtonItem setTintColor:UIColorFromRGB(0x333333)];
    self.navigationItem.leftBarButtonItem = backButtonItem;
    
    UIButton *moreBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    [moreBtn addTarget:self action:@selector(moreAction:) forControlEvents:UIControlEventTouchUpInside];
    [moreBtn setImage:[UIImage imageNamed:@"LFTMC_Setting"] forState:UIControlStateNormal];
    [moreBtn sizeToFit];
    UIBarButtonItem *moreBtnItem = [[UIBarButtonItem alloc] initWithCustomView:moreBtn];
    
    self.navigationItem.rightBarButtonItem = moreBtnItem;
    
//    self.navigationItem.title = [self sessionTitle];
    NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:self.session.sessionId];
    UIView *titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
    
    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 20)];
    titleLabel.text = [self sessionTitle];
    titleLabel.numberOfLines = 1;
    titleLabel.textColor = UIColorFromRGB(0x999999);
//    titleLabel.font = [UIFont systemFontOfSize:14];
    titleLabel.adjustsFontSizeToFitWidth = YES;
    titleLabel.textAlignment = NSTextAlignmentCenter;
    titleLabel.tag = 1;
//    [titleLabel sizeToFit];
    UILabel *countLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 200, 20)];
    countLabel.text = [NSString stringWithFormat:@"%ld人参与课程", [team memberNumber]];
    countLabel.textColor = UIColorFromRGB(0xCCCCCC);
    countLabel.font = [UIFont systemFontOfSize:12];
    countLabel.textAlignment = NSTextAlignmentCenter;
    countLabel.tag = 2;
//    [countLabel sizeToFit];
    [titleView addSubview:titleLabel];
    [titleView addSubview:countLabel];
    
    self.navigationItem.titleView = titleView;

}

- (void)refreshNav {
    UIView *titleView = self.navigationItem.titleView;
    for (UILabel *label in titleView.subviews) {
        if (label.tag == 1) {
            label.text = [self sessionTitle];
        } else if (label.tag == 2) {
            NIMTeam *team = [[NIMSDK sharedSDK].teamManager teamById:self.session.sessionId];
            label.text = [NSString stringWithFormat:@"%ld人参与课程", [team memberNumber]];
        }
    }
}

- (void)setupStatusView {
    CGFloat statusViewHeight = 71.6f;
    CGFloat screenHeight     = UIScreenHeight;
    CGRect frame = CGRectMake(0, screenHeight - statusViewHeight, self.view.nim_width, statusViewHeight);
    NIMTeamMember *teamMemberInfo = [[NIMSDK sharedSDK].teamManager teamMember:[LFTMCUtil sharedInstance].teamModel.accountId inTeam:[LFTMCUtil sharedInstance].teamModel.teamId];
    self.statusView = [[LFTMCStatusHintView alloc] initWithFrame:frame teamMemberInfo:teamMemberInfo];
    [self.view addSubview:self.statusView];
}

- (void)setupUnreadAlertView {
    
    NSArray *recents = [NIMSDK sharedSDK].conversationManager.allRecentSessions;
    NIMRecentSession *recentSession;
    for (NIMRecentSession *recent in recents) {
        if ([recent.session.sessionId isEqualToString:self.session.sessionId]) {
            recentSession = recent;
            break;
        }
    }
    NSUInteger unreadCount = 0;
    if (recentSession && recentSession.unreadCount) {
        unreadCount = recentSession.unreadCount;
    }
    
    if (!self.unreadAlert) {
        self.unreadAlert = [[LFTMCUnReadAlertView alloc] init];
        self.unreadAlert.delegate = self;
        [self.unreadAlert resetSelf];
        [self.unreadAlert updateCount:unreadCount];
        [self.view addSubview:self.unreadAlert];
    }

    CGFloat screenWidth  = [UIScreen mainScreen].bounds.size.width;
    CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
    CGFloat x = screenWidth / 2;
    CGFloat y = 100.f;
    self.unreadAlert.center = CGPointMake(x, y);
    
}

#pragma LFTMCUnReadAlertViewDelegate
- (void)didClickLFTMCUnreadAlertView {
    [[LFTMCUtil sharedInstance].dataSource lftmc_trackEventID:@"IMNoticeClick"
                                                     category:nil
                                                        label:nil
                                                   attributes:nil];
    [self.tableView lftmc_scrollToBottom:YES];
    [self.unreadAlert resetSelf];
    [[NIMSDK sharedSDK].conversationManager markAllMessagesReadInSession:self.session.sessionId];
}

- (void)didScrollToButtom {
    [self.unreadAlert resetSelf];
    [[NIMSDK sharedSDK].conversationManager markAllMessagesReadInSession:self.session.sessionId];
}

#pragma mark - NIMTeamManagerDelegate

// 用作群被禁言的操作
// 还有数据的更新
- (void)onTeamUpdated:(NIMTeam *)team {
    
    [[NIMSDK sharedSDK].teamManager fetchTeamInfo:team.teamId completion:^(NSError * _Nullable error, NIMTeam * _Nullable team) {
        if (!error) {
            [LFTMCUtil sharedInstance].customInfo = [LFTMCUtil stringToDictionary:team.serverCustomInfo];
            [[NIMSDK sharedSDK].teamManager fetchTeamMutedMembers:team.teamId completion:^(NSError * _Nullable error, NSArray<NIMTeamMember *> * _Nullable members) {
                if (!error) {
                    [LFTMCUtil sharedInstance].mutedMembers = members;
                    LFTMCStatus status = [LFTMCUtil statusForTeamByModel:[LFTMCUtil sharedInstance].teamModel mutedMembers:[LFTMCUtil sharedInstance].mutedMembers];
                    NIMTeamMember *member = [LFTMCUtil sharedInstance].myTeamInfo;
                    if (status != LFTMCStatusCourseEnded &&
                        ![LFTMCUtil isOwnerOrManager:member]) {
                        
                        if (status == LFTMCStatusPersonMuted || status == LFTMCStatusTeamMuted) {
                            [self.sessionInputView endEditing:YES];
                        }
                        
                        [self.statusView refreshStatus:status];
                    } else if (status == LFTMCStatusCourseEnded){
                        [self.sessionInputView endEditing:YES];
                        [self.statusView refreshStatus:status];
                    }
                }
            }];
        }
        
    }];
    
}

// 用作个人被禁言的操作
- (void)onTeamMemberChanged:(NIMTeam *)team
{
    [[NIMSDK sharedSDK].teamManager fetchTeamMutedMembers:team.teamId completion:^(NSError * _Nullable error, NSArray<NIMTeamMember *> * _Nullable members) {
        if (!error) {
            [LFTMCUtil sharedInstance].mutedMembers = members;
            LFTMCStatus status = [LFTMCUtil statusForTeamByModel:[LFTMCUtil sharedInstance].teamModel mutedMembers:members];
            NIMTeamMember *member = [LFTMCUtil sharedInstance].myTeamInfo;
            if (status == LFTMCStatusPersonMuted &&
                ![LFTMCUtil isOwnerOrManager:member]) {
                [self.sessionInputView endEditing:YES];
            }
            [self.statusView refreshStatus:status];
        }
    }];
    
    
    [[NIMSDK sharedSDK].teamManager fetchTeamMembers:team.teamId completion:^(NSError * _Nullable error, NSArray<NIMTeamMember *> * _Nullable members) {
        if (!error) {
            for (NIMTeamMember *member in members) {
                NSString *me = [[NIMSDK sharedSDK].loginManager currentAccount];
                if ([member.userId isEqualToString:me]) {
                    [LFTMCUtil sharedInstance].myTeamInfo = member;
                    break;
                }
            }
        }
    }];
}

- (void)LFTMC_AddListener
{
    [[[NIMSDK sharedSDK] teamManager] addDelegate:self];
    [[[NIMSDK sharedSDK] loginManager] addDelegate:self];
    [[[NIMSDK sharedSDK] systemNotificationManager] addDelegate:self];
    [[NIMSDKConfig sharedConfig] setDelegate:self];
}

- (void)LFTMC_RemoveListener
{
    [[NIMSDKConfig sharedConfig] setDelegate:nil];
    [[[NIMSDK sharedSDK] chatManager] removeDelegate:self];
    [[[NIMSDK sharedSDK] conversationManager] removeDelegate:self];
    [[[NIMSDK sharedSDK] mediaManager] removeDelegate:self];
    [[[NIMSDK sharedSDK] systemNotificationManager] removeDelegate:self];
}


#pragma NIMLoginManagerDelegate
-(void)onKick:(NIMKickReason)code clientType:(NIMLoginClientType)clientType
{
    NSString *reason = @"你被踢下线";
    switch (code) {
        case NIMKickReasonByClient:
        case NIMKickReasonByClientManually:{
            reason = @"你的帐号在其他设备登录，当前设备将会退出";
            break;
        }
        case NIMKickReasonByServer:
            reason = @"你被服务器踢下线";
            break;
        default:
            break;
    }
    [[[NIMSDK sharedSDK] loginManager] logout:^(NSError *error) {
        UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:@"下线通知" message:reason preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *quit = [UIAlertAction actionWithTitle:@"知道了" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            [self close];
        }];
        [alertVC addAction:quit];
        [self presentViewController:alertVC animated:YES completion:nil];
    }];
}


- (void)onAutoLoginFailed:(NSError *)error
{
    //只有连接发生严重错误才会走这个回调，在这个回调里应该登出，返回界面等待用户手动重新登录。
    DDLogInfo(@"onAutoLoginFailed %zd",error.code);
    NSString *toast = [NSString stringWithFormat:@"登录失败: %zd",error.code];
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    [window makeToast:toast duration:2.0 position:CSToastPositionCenter];
    [self close];
}

#pragma NIMSDKConfigDelegate
- (BOOL)shouldIgnoreNotification:(NIMNotificationObject *)notification
{
    BOOL ignore = YES;
    NIMTeamNotificationContent *content = (NIMTeamNotificationContent *)[notification content];
    id attachment = [content attachment];
    if ([attachment isKindOfClass:[NIMUpdateTeamInfoAttachment class]]) {
        NIMUpdateTeamInfoAttachment *teamAttachment = (NIMUpdateTeamInfoAttachment *)attachment;
        if ([teamAttachment.values count] == 1) {
            NIMTeamUpdateTag tag = [[[teamAttachment.values allKeys] firstObject] integerValue];
            // 仅保留群禁言这一类通知消息
            if (tag == NIMTeamUpdateTagMuteMode) {
                ignore = NO;
            }
            
        }
    }
    
    return ignore;
}

- (BOOL)shouldAutorotate {
    return !self.currentSingleSnapView;
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}


@end
